package com.spy.material.service.impl;

import java.math.BigDecimal;
import java.sql.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeParseException;
import java.util.List;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.spy.common.exception.base.BaseException;
import com.spy.common.utils.DateUtils;
import com.spy.material.domain.Inventory;
import com.spy.material.domain.InventoryDetail;
import com.spy.material.domain.OutboundOrderDetail;
import com.spy.material.dto.OutboundOrderCreateDTO;
import com.spy.material.dto.OutboundOrderDetailCreateDTO;
import com.spy.material.dto.OutboundOrderQueryDTO;
import com.spy.material.mapper.InventoryDetailMapper;
import com.spy.material.mapper.InventoryMapper;
import com.spy.material.mapper.OutboundOrderDetailMapper;
import com.spy.material.vo.OutboundOrderPageVO;
import com.spy.material.vo.OutboundOrderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.spy.material.mapper.OutboundOrderMapper;
import com.spy.material.domain.OutboundOrder;
import com.spy.material.service.IOutboundOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Arrays;
/**
 * 出库管理Service业务层处理
 * 
 * @author twc
 * @date 2025-11-09
 */
@Service
public class OutboundOrderServiceImpl extends ServiceImpl<OutboundOrderMapper, OutboundOrder> implements IOutboundOrderService
{
    @Autowired
    private OutboundOrderMapper outboundOrderMapper;
    @Autowired
    private OutboundOrderDetailMapper outboundOrderDetailMapper;
    @Autowired
    private InventoryMapper inventoryMapper;
    @Autowired
    private InventoryDetailMapper inventoryDetailMapper;

    /**
     * 查询出库管理
     * 
     * @param id 出库管理主键
     * @return 出库管理
     */
    @Override
    public OutboundOrder selectOutboundOrderById(Long id)
    {
                return getById(id);
    }

    /**
     * 查询出库管理列表
     * 
     * @param outboundOrder 出库管理
     * @return 出库管理
     */
    @Override
    public List<OutboundOrder> selectOutboundOrderList(OutboundOrder outboundOrder)
    {
        return outboundOrderMapper.selectOutboundOrderList(outboundOrder);
    }

    /**
     * 新增出库管理
     * 
     * @param outboundOrder 出库管理
     * @return 结果
     */
    @Override
    public int insertOutboundOrder(OutboundOrder outboundOrder)
    {
        outboundOrder.setCreateTime(DateUtils.getNowDate());
                return save(outboundOrder) ? 1 : 0;
    }

    /**
     * 修改出库管理
     * 
     * @param outboundOrder 出库管理
     * @return 结果
     */
    @Override
    public int updateOutboundOrder(OutboundOrder outboundOrder)
    {
        outboundOrder.setUpdateTime(DateUtils.getNowDate());
                return updateById(outboundOrder) ? 1 : 0;
    }

    /**
     * 批量删除出库管理
     * 
     * @param ids 需要删除的出库管理主键
     * @return 结果
     */
    @Override
    public int deleteOutboundOrderByIds(Long[] ids)
    {
                return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除出库管理信息
     * 
     * @param id 出库管理主键
     * @return 结果
     */
    @Override
    public int deleteOutboundOrderById(Long id)
    {
                return removeById(id) ? 1 : 0;
    }

    @Override
    public OutboundOrderPageVO all(OutboundOrderQueryDTO outboundOrderQueryDTO) {
        PageHelper.startPage(outboundOrderQueryDTO.getPage(),outboundOrderQueryDTO.getPageSize());
        Page<OutboundOrderVO> page = outboundOrderMapper.all(outboundOrderQueryDTO);
        OutboundOrderPageVO outboundOrderPageVO = new OutboundOrderPageVO();
        outboundOrderPageVO.setTotal(page.getTotal());
        outboundOrderPageVO.setRows(page.getResult());

        return outboundOrderPageVO;
    }

//    @Override
//    @Transactional
//    public void add(OutboundOrderCreateDTO outboundOrderCreateDTO) {
//        OutboundOrder outboundOrder = new OutboundOrder();
//        BeanUtils.copyProperties(outboundOrderCreateDTO,outboundOrder);
//        outboundOrderMapper.insertOutboundOrder(outboundOrder);
//
//        for (OutboundOrderDetail outboundOrderDetail : outboundOrderCreateDTO.getDetails()){
//            outboundOrderDetail.setOutboundOrderId(outboundOrder.getId());
//            outboundOrderDetailMapper.insertOutboundOrderDetail(outboundOrderDetail);
//        }
//
//    }

    @Override
    @Transactional
    public void add(@RequestBody OutboundOrderCreateDTO outboundOrderCreateDTO) {
        // 1. 保存出库单主表
        OutboundOrder outboundOrder = new OutboundOrder();
        BeanUtils.copyProperties(outboundOrderCreateDTO, outboundOrder);
        outboundOrderMapper.insertOutboundOrder(outboundOrder);

        // 2. 保存出库明细并更新库存
        for (OutboundOrderDetailCreateDTO detailDTO : outboundOrderCreateDTO.getDetails()) {
            // 将DTO转换为实体
            OutboundOrderDetail outboundOrderDetail = new OutboundOrderDetail();
            BeanUtils.copyProperties(detailDTO, outboundOrderDetail);
            outboundOrderDetail.setOutboundOrderId(outboundOrder.getId());
            outboundOrderDetailMapper.insertOutboundOrderDetail(outboundOrderDetail);

            // 3. 更新库存总表
            updateInventory(outboundOrderCreateDTO, detailDTO, outboundOrder);

            // 4. 记录库存明细
            addInventoryDetail(outboundOrderCreateDTO, detailDTO, outboundOrder, outboundOrderDetail);
        }
    }

    /**
     * 更新库存总表
     */
    private void updateInventory(OutboundOrderCreateDTO outboundOrderCreateDTO,
                                 OutboundOrderDetailCreateDTO detailDTO,
                                 OutboundOrder outboundOrder) {
        // 查询当前库存记录
        Inventory inventory = inventoryMapper.selectByMaterialAndFullName(
                detailDTO.getMaterialName(),
                outboundOrderCreateDTO.getFullName()
        );

        if (inventory == null) {
            throw new BaseException("物料 " + detailDTO.getMaterialName() + " 在组织 " +
                    outboundOrderCreateDTO.getFullName() + " 中不存在");
        }

        // 检查库存是否足够
        if (inventory.getCurrentStock() < detailDTO.getOutboundQuantity()) {
            throw new BaseException("物料 " + detailDTO.getMaterialName() + " 库存不足，当前库存：" +
                    inventory.getCurrentStock() + "，出库数量：" + detailDTO.getOutboundQuantity());
        }

        // 更新库存数量和金额
        int newStock = inventory.getCurrentStock() - detailDTO.getOutboundQuantity();
        BigDecimal newTotalAmount = inventory.getUnitPrice().multiply(new BigDecimal(newStock));

        inventory.setCurrentStock(newStock);
        inventory.setTotalAmount(newTotalAmount);

        inventoryMapper.updateInventory(inventory);
    }

    /**
     * 记录库存明细
     */
    private void addInventoryDetail(OutboundOrderCreateDTO outboundOrderCreateDTO,
                                    OutboundOrderDetailCreateDTO detailDTO,
                                    OutboundOrder outboundOrder,
                                    OutboundOrderDetail outboundOrderDetail) {
        InventoryDetail inventoryDetail = new InventoryDetail();

        // 设置基本信息
        inventoryDetail.setMaterialName(detailDTO.getMaterialName());
        inventoryDetail.setMaterialCategory(detailDTO.getMaterialCategory());
        inventoryDetail.setUnit(detailDTO.getUnit());
        inventoryDetail.setFullName(outboundOrderCreateDTO.getFullName());
        inventoryDetail.setTransactionType("出库");
        inventoryDetail.setDocumentNumber(outboundOrder.getOutboundOrderNumber());
        inventoryDetail.setQuantity(-detailDTO.getOutboundQuantity());
        // 将字符串日期转换为 LocalDateTime，时间部分设置为当前时间
        try {
            LocalDate localDate = LocalDate.parse(outboundOrderCreateDTO.getOutboundDate());
            LocalDateTime transactionDateTime = localDate.atTime(LocalTime.now());
            inventoryDetail.setTransactionDate(transactionDateTime);
        } catch (DateTimeParseException e) {
            throw new BaseException("出库日期格式错误，应为 YYYY-MM-DD 格式");
        }

        // 查询更新后的当前库存
        Inventory currentInventory = inventoryMapper.selectByMaterialAndFullName(
                detailDTO.getMaterialName(),
                outboundOrderCreateDTO.getFullName()
        );
        inventoryDetail.setCurrentStock(currentInventory.getCurrentStock());

        // 设置关联ID
        inventoryDetail.setInventoryId(currentInventory.getId());
        inventoryDetail.setOutboundOrderId(outboundOrder.getId());

        inventoryDetailMapper.insertInventoryDetail(inventoryDetail);
    }
}
